<script setup>
import { ref, onMounted, onBeforeUnmount } from 'vue'

const canvasRef = ref(null)
const gameLoop = ref(null)
const score = ref(0)
const isGameOver = ref(false)

// 游戏状态
const gameState = ref({
  player: {
    x: 100,
    y: 400,
    width: 30,
    height: 60,
    speed: 6,
    jumping: false,
    jumpPower: 18,
    gravity: 0.8,
    velocityY: 0,
  },
  shuttle: {
    x: 300,
    y: 200,
    radius: 5,
    speed: 4,
    velocityX: -4,
    velocityY: 2,
    gravity: 0.3,
    maxSpeed: 12,
  },
  keys: {
    left: false,
    right: false,
    up: false,
  },
})

// 绘制火柴人
const drawStickman = (ctx, x, y) => {
  ctx.strokeStyle = '#000'
  ctx.lineWidth = 2

  // 头部
  ctx.beginPath()
  ctx.arc(x + 15, y + 10, 10, 0, Math.PI * 2)
  ctx.stroke()

  // 身体
  ctx.beginPath()
  ctx.moveTo(x + 15, y + 20)
  ctx.lineTo(x + 15, y + 40)
  ctx.stroke()

  // 手臂
  ctx.beginPath()
  ctx.moveTo(x + 15, y + 25)
  ctx.lineTo(x, y + 35)
  ctx.moveTo(x + 15, y + 25)
  ctx.lineTo(x + 30, y + 35)
  ctx.stroke()

  // 腿
  ctx.beginPath()
  ctx.moveTo(x + 15, y + 40)
  ctx.lineTo(x + 5, y + 60)
  ctx.moveTo(x + 15, y + 40)
  ctx.lineTo(x + 25, y + 60)
  ctx.stroke()
}

// 绘制羽毛球
const drawShuttle = (ctx, x, y) => {
  ctx.fillStyle = '#fff'
  ctx.strokeStyle = '#000'
  ctx.lineWidth = 1

  ctx.beginPath()
  ctx.arc(x, y, 5, 0, Math.PI * 2)
  ctx.fill()
  ctx.stroke()

  // 绘制羽毛
  ctx.beginPath()
  ctx.moveTo(x, y)
  ctx.lineTo(x - 8, y - 8)
  ctx.moveTo(x, y)
  ctx.lineTo(x - 8, y)
  ctx.moveTo(x, y)
  ctx.lineTo(x - 8, y + 8)
  ctx.stroke()
}

// 更新游戏状态
const updateGame = () => {
  const player = gameState.value.player
  const shuttle = gameState.value.shuttle
  const keys = gameState.value.keys

  // 更新玩家水平位置
  if (keys.left && player.x > 0) {
    player.x -= player.speed
  }
  if (keys.right && player.x < 570) {
    player.x += player.speed
  }

  // 跳跃逻辑
  if (keys.up && !player.jumping) {
    player.jumping = true
    player.velocityY = -player.jumpPower
  }

  // 应用重力和垂直移动
  player.velocityY += player.gravity
  player.y += player.velocityY

  // 地面碰撞检测
  if (player.y > 400) {
    player.y = 400
    player.velocityY = 0
    player.jumping = false
  }

  // 更新羽毛球位置
  shuttle.x += shuttle.velocityX
  shuttle.y += shuttle.velocityY
  shuttle.velocityY += shuttle.gravity

  // 限制羽毛球速度
  if (Math.abs(shuttle.velocityX) > shuttle.maxSpeed) {
    shuttle.velocityX = Math.sign(shuttle.velocityX) * shuttle.maxSpeed
  }
  if (Math.abs(shuttle.velocityY) > shuttle.maxSpeed) {
    shuttle.velocityY = Math.sign(shuttle.velocityY) * shuttle.maxSpeed
  }

  // 球拍击球检测
  const dx = shuttle.x - (player.x + 15)
  const dy = shuttle.y - (player.y + 35)
  const distance = Math.sqrt(dx * dx + dy * dy)

  if (distance < 30) {
    // 改进击球效果
    const angle = Math.atan2(dy, dx)
    const power = 10

    shuttle.velocityX = Math.cos(angle) * power
    shuttle.velocityY = Math.min(-8, Math.sin(angle) * power - 2)

    // 根据击球位置添加额外效果
    if (player.jumping) {
      shuttle.velocityY -= 2 // 跳跃击球给予额外上升力
    }

    score.value++
  }

  // 边界检查
  if (shuttle.x < 0) {
    shuttle.x = 0
    shuttle.velocityX = Math.abs(shuttle.velocityX) * 0.8 // 减少反弹速度
  }
  if (shuttle.x > 600) {
    shuttle.x = 600
    shuttle.velocityX = -Math.abs(shuttle.velocityX) * 0.8 // 减少反弹速度
  }

  // 游戏结束检测 - 羽毛球触地即结束
  if (shuttle.y > 460) {
    isGameOver.value = true
    stopGame()
  }
}

// 绘制游戏
const drawGame = () => {
  const canvas = canvasRef.value
  const ctx = canvas.getContext('2d')

  // 清空画布
  ctx.clearRect(0, 0, canvas.width, canvas.height)

  // 绘制背景
  ctx.fillStyle = '#87CEEB'
  ctx.fillRect(0, 0, canvas.width, canvas.height)

  // 绘制地面
  ctx.fillStyle = '#90EE90'
  ctx.fillRect(0, 460, canvas.width, 40)

  // 绘制分数
  ctx.fillStyle = '#000'
  ctx.font = '24px Arial'
  ctx.fillText(`得分: ${score.value}`, 20, 30)

  // 绘制火柴人和羽毛球
  drawStickman(ctx, gameState.value.player.x, gameState.value.player.y)
  drawShuttle(ctx, gameState.value.shuttle.x, gameState.value.shuttle.y)

  if (isGameOver.value) {
    ctx.fillStyle = 'rgba(0, 0, 0, 0.5)'
    ctx.fillRect(0, 0, canvas.width, canvas.height)
    ctx.fillStyle = '#fff'
    ctx.font = '48px Arial'
    ctx.fillText('游戏结束', 200, 200)
    ctx.font = '24px Arial'
    ctx.fillText(`最终得分: ${score.value}`, 240, 250)
    ctx.fillText('按空格键重新开始', 220, 300)
  }
}

// 游戏主循环
const startGameLoop = () => {
  if (gameLoop.value) return

  gameLoop.value = setInterval(() => {
    if (!isGameOver.value) {
      updateGame()
    }
    drawGame()
  }, 1000 / 60)
}

// 停止游戏
const stopGame = () => {
  if (gameLoop.value) {
    clearInterval(gameLoop.value)
    gameLoop.value = null
  }
}

// 重置游戏
const resetGame = () => {
  gameState.value = {
    player: {
      x: 100,
      y: 400,
      width: 30,
      height: 60,
      speed: 6,
      jumping: false,
      jumpPower: 18,
      gravity: 0.8,
      velocityY: 0,
    },
    shuttle: {
      x: 300,
      y: 200,
      radius: 5,
      speed: 4,
      velocityX: -4,
      velocityY: 2,
      gravity: 0.3,
      maxSpeed: 12,
    },
    keys: {
      left: false,
      right: false,
      up: false,
    },
  }
  score.value = 0
  isGameOver.value = false
  startGameLoop()
}

// 键盘事件处理
const handleKeyDown = (e) => {
  if (isGameOver.value && e.code === 'Space') {
    resetGame()
    return
  }

  switch (e.code) {
    case 'ArrowLeft':
      gameState.value.keys.left = true
      break
    case 'ArrowRight':
      gameState.value.keys.right = true
      break
    case 'ArrowUp':
    case 'Space':
      gameState.value.keys.up = true
      break
  }
}

const handleKeyUp = (e) => {
  switch (e.code) {
    case 'ArrowLeft':
      gameState.value.keys.left = false
      break
    case 'ArrowRight':
      gameState.value.keys.right = false
      break
    case 'ArrowUp':
    case 'Space':
      gameState.value.keys.up = false
      break
  }
}

// 生命周期钩子
onMounted(() => {
  window.addEventListener('keydown', handleKeyDown)
  window.addEventListener('keyup', handleKeyUp)
  resetGame()
})

onBeforeUnmount(() => {
  window.removeEventListener('keydown', handleKeyDown)
  window.removeEventListener('keyup', handleKeyUp)
  stopGame()
})
</script>

<template>
  <div class="game-container">
    <canvas ref="canvasRef" width="600" height="500"></canvas>
    <div class="controls">
      <p>控制说明：</p>
      <ul>
        <li>← → 键左右移动火柴人</li>
        <li>↑ 或空格键跳跃</li>
        <li>用火柴人接住羽毛球得分</li>
        <li>羽毛球落地即游戏结束</li>
        <li>游戏结束后按空格键重新开始</li>
      </ul>
    </div>
  </div>
</template>

<style scoped>
.game-container {
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 20px;
}

canvas {
  border: 2px solid #333;
  border-radius: 8px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
}

.controls {
  margin-top: 20px;
  padding: 15px;
  background: #fff;
  border-radius: 8px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}

.controls p {
  margin: 0 0 10px 0;
  font-weight: bold;
}

.controls ul {
  margin: 0;
  padding-left: 20px;
}

.controls li {
  margin: 5px 0;
  color: #666;
}
</style>
